home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 3: CDPD 3 / Almathera Ten on Ten - Disc 3: CDPD3.iso / fish / 001-100 / 001-025 / 004 / mandel / mand3.c < prev    next >
C/C++ Source or Header  |  1995-03-17  |  16KB  |  497 lines

  1. /*
  2.                   MAND3.C - Control routines
  3.              Mandelbrot Self-Squared Dragon Generator
  4.                     For the Commodore Amiga
  5.                          Version 1.00
  6.  
  7.              Copyright (C) 1985, Robert S. French
  8.                   Placed in the Public Domain
  9.  
  10.      Assorted Goodies and Intuition-stuff by =RJ Mical=  1985
  11.  
  12. This program may be distributed free of charge as long as the above
  13. notice is retained.
  14.  
  15. */
  16.  
  17.  
  18. #include "mand.h"
  19.  
  20. #ifndef INTUITICKS    /* Not in earlier pre-V1.1 header files */
  21. #define INTUITICKS  0x00400000
  22. #endif
  23.  
  24. extern int MathBase, MathTransBase;
  25.  
  26. extern struct Menu MainMenu[MENU_COUNT];
  27.  
  28.  
  29. /*----------------------*/
  30. /* Graphics definitions */
  31.  
  32. extern struct   GfxBase       *GfxBase;
  33. extern struct   IntuitionBase *IntuitionBase;
  34.  
  35. struct   RastPort      *rp,*rp2;
  36. struct   ViewPort      *vp;
  37.  
  38. struct TextAttr TextFont =
  39.     {
  40.     "topaz.font", /* Standard system font */
  41.     8,    0,    0
  42.     };
  43.  
  44. struct   Window        *w,*w2;
  45. struct   Screen        *screen;
  46. struct   IntuiMessage  *message;
  47.  
  48. struct NewScreen ns = {
  49.    0, 0,                               /* start position                */
  50.    320, 200, 6,                        /* width, height, depth          */
  51.    0, 1,                               /* detail pen, block pen         */
  52.    HAM,                                /* Hold and Modify ViewMode      */
  53.    CUSTOMSCREEN,                       /* screen type                   */
  54.    &TextFont,                          /* font to use                   */
  55.    "",                                 /* default title for screen      */
  56.    NULL                                /* pointer to additional gadgets */
  57.    };
  58.  
  59. struct NewWindow nw = {
  60.    0, 0,                          /* start position                */
  61.    320, 200,                      /* width, height                 */
  62.    -1, -1,                        /* detail pen, block pen         */
  63.    MOUSEBUTTONS | MENUPICK | INTUITICKS,
  64.                                   /* IDCMP flags                   */
  65.    ACTIVATE | BORDERLESS | BACKDROP,
  66.                                   /* window flags                  */
  67.    NULL,                          /* pointer to first user gadget  */
  68.    NULL,                          /* pointer to user checkmark     */
  69.    NULL,                          /* window title                  */
  70.    NULL,                          /* pointer to screen (set below) */
  71.    NULL,                          /* pointer to superbitmap        */
  72.    0, 0, 320, 200,                /* ignored since not sizeable    */
  73.    CUSTOMSCREEN                   /* type of screen desired        */
  74. };
  75.  
  76. struct NewWindow aw = {
  77.    0, 10,
  78.    100, 70,
  79.    -1, -1,
  80.    NULL,
  81.    WINDOWDRAG|WINDOWSIZING|SMART_REFRESH,
  82.    NULL,
  83.    NULL,
  84.    "Analysis",
  85.    NULL,
  86.    NULL,
  87.    0, 0, 320, 200,
  88.    CUSTOMSCREEN
  89. };
  90.  
  91. long last_color;
  92.  
  93. BOOL SettingCenter, SettingBoxSize;
  94.  
  95. /*----------------------------------*/
  96. /* Miscellaneous Global Definitions */
  97.  
  98. extern union kludge {
  99.    float f;
  100.    int i;
  101. } start_r,end_r,start_i,end_i;  /* Block bounds for set */
  102. extern int max_x,max_y;  /* Graphics window size */
  103. extern int max_count,color_inc,color_offset,color_set,color_mode,color_div;
  104. extern int color_inset,func_num;
  105.  
  106. extern int v_starty,max_mem, max_mem_y;
  107. extern long v_offset;
  108. extern UWORD *color_table,*v_mand_store;
  109.  
  110. extern int modified,want_read;
  111.  
  112. extern FILE *console,*v_fp,*redir_fp;
  113.  
  114. extern SHORT ZoomCenterX, ZoomCenterY, ZoomBoxSizeX, ZoomBoxSizeY;
  115. extern SHORT ZoomBoxStartX, ZoomBoxStartY;
  116.  
  117.  
  118. open_winds()
  119. {
  120.    int i,color;
  121.  
  122.    nw.Width = max_x;
  123.    nw.Height = max_y+STARTY;
  124.  
  125.    if (color_mode & NOT_HOLDANDMODIFY) {
  126.       ns.ViewModes = NULL;
  127.       ns.Depth = 5;
  128.    }
  129.    else {
  130.       ns.ViewModes = HAM;
  131.       ns.Depth = 6;
  132.    }
  133.  
  134.    if (color_mode & INTERLACE_MODE) {
  135.       ns.Height = 400;
  136.    }
  137.    else
  138.       ns.Height = 200;
  139.  
  140.    if (color_mode & HIRES_MODE) {
  141.       ns.Width = 640;
  142.       ns.ViewModes |= HIRES;
  143.       ns.Depth = 4;
  144.    }
  145.    else
  146.       ns.Width = 320;
  147.  
  148.    screen = (struct Screen *)OpenScreen(&ns);
  149.    if (screen == NULL) {
  150.       fputs("Can't open new screen!\n",console);
  151.       return (1);
  152.    }
  153.  
  154.    ShowTitle(screen,FALSE);
  155.  
  156.    nw.Screen = screen;
  157.    w = (struct Window *)OpenWindow(&nw);
  158.    if (w == NULL) {
  159.       CloseScreen(screen);
  160.       fputs("Can't open new window!\n",console);
  161.       return (1);
  162.    }
  163.  
  164.    SetMenuStrip(w, &MainMenu[0]);
  165.  
  166.    vp = &screen->ViewPort;
  167.    rp = w->RPort;
  168.  
  169.    SetDrMd(rp,JAM1);
  170.    SetBPen(rp, 0);
  171.  
  172.    /* leave registers 0 and 1 alone, set two to black, set the others
  173.     * according to the user's design
  174.     */
  175.    for (i = 2; i <= 31; i++) {
  176.       if (i == 2) color = 0;
  177.       else color = *(color_table + color_offset + (i - 2) * color_inc);
  178.       SetRGB4(vp, i, (color >> 8) & 0xf, (color >> 4) & 0xf, color & 0xf);
  179.    }
  180.  
  181.    return (0);
  182. }
  183.  
  184. void wait_close()
  185. {
  186.    ULONG class;
  187.    USHORT code;
  188.    union kludge center, distance, scale;
  189.  
  190.    if (redir_fp)
  191.       {
  192.       Delay(600);
  193.       CloseDisplay();
  194.       return;
  195.       }
  196.  
  197.    SettingCenter = SettingBoxSize = FALSE;
  198.  
  199.    for (EVER)
  200.       {
  201.       Wait((1 << w->UserPort->mp_SigBit));
  202.       while (message = (struct IntuiMessage *)GetMsg(w->UserPort))
  203.          {
  204.          class = message->Class;
  205.          code  = message->Code;
  206.          ReplyMsg(message);
  207.  
  208.          switch (class)
  209.             {
  210.             case MENUPICK:
  211.                switch MENUNUM(code)
  212.                   {
  213.                   case MENU_OPTIONS:
  214.                      switch ITEMNUM(code)
  215.                         {
  216.                         case OPTIONS_QUARTER:
  217.                            if (color_mode & HIRES_MODE) max_x = 640 / 4;
  218.                            else max_x = 320 / 4;
  219.                            if (color_mode & INTERLACE_MODE) max_y = 400 / 4;
  220.                            else max_y = 200 / 4;
  221.                            max_mem = max_mem_y * MAXX;
  222.                            max_mem /= max_x;
  223.                            if (gen_mand()) return;
  224.                            break;
  225.                         case OPTIONS_FULL:
  226.                            if (color_mode & HIRES_MODE) max_x = 640;
  227.                            else max_x = 320;
  228.                            if (color_mode & INTERLACE_MODE) max_y = 400;
  229.                            else max_y = 200;
  230.                            max_mem = max_mem_y * MAXX;
  231.                            max_mem /= max_x;
  232.  
  233.                            /* intentionally fall into GENERATE */
  234.                         case OPTIONS_GENERATE:
  235.                            if (gen_mand()) return;
  236.                            break;
  237.                         case OPTIONS_CLOSE:
  238.                            CloseDisplay();
  239.                            fclose(v_fp);
  240.                            v_fp = NULL;
  241.                            return;
  242.                         }
  243.                      break;
  244.                   case MENU_ZOOM:
  245.                      switch ITEMNUM(code)
  246.                         {
  247.                         case ZOOM_SETCENTER:
  248.                            if (NOT SettingCenter)
  249.                               {
  250.                               ZoomCenterX = w->MouseX;
  251.                               ZoomCenterY = w->MouseY;
  252.                               DrawZoomCenter();
  253.                               SettingCenter = TRUE;
  254.                               }
  255.                            break;
  256.                         case ZOOM_SIZEBOX:
  257.                            if (NOT SettingBoxSize)
  258.                               {
  259.                               RecalcZoomBox();
  260.                               DrawZoomBox();
  261.                               SettingBoxSize = TRUE;
  262.                               }
  263.                            break;
  264.                         case ZOOM_ZOOMIN:
  265.                         case ZOOM_ZOOMIN10:
  266.                            /* first, get distance equal to the current size 
  267.                             * of a single pixel width 
  268.                             */
  269.                            distance.i = SPSub(start_r.i,end_r.i);
  270.                            distance.i = SPDiv(SPFlt(max_x), distance.i);
  271.                            /* center equals the number of pixels from the
  272.                             * center of the display to the zoom center
  273.                             */
  274.                            center.i = SPSub(SPFlt(max_x >> 1), 
  275.                                  SPFlt(ZoomCenterX));
  276.                            /* scale equals the real displacement from the
  277.                             * center of the display to the zoom center
  278.                             */
  279.                            scale.i = SPMul(distance.i, center.i);
  280.                /* so, translate the real origin to here */
  281.                            start_r.i = SPAdd(scale.i,start_r.i);
  282.                            end_r.i = SPAdd(scale.i,end_r.i);
  283.  
  284.                            /* now do it all again for the irrational axis */
  285.                            distance.i = SPSub(start_i.i,end_i.i);
  286.                            distance.i = SPDiv(SPFlt(max_y), distance.i);
  287.                /* the arguments are reversed to swap the sign */
  288.                            center.i = SPSub(SPFlt(ZoomCenterY), 
  289.                                  SPFlt(max_y >> 1));
  290.                            scale.i = SPMul(distance.i, center.i);
  291.                /* so, translate the real origin to here */
  292.                            start_i.i = SPAdd(scale.i,start_i.i);
  293.                            end_i.i = SPAdd(scale.i,end_i.i);
  294.  
  295.                            /* next, get the zoom-in scale
  296.                             * if we're using the frame, then get the 
  297.                             * proportion of the box to the display;
  298.                             * else if we're zooming in by 10, get that scale
  299.                             */
  300.                            if (ITEMNUM(code) == ZOOM_ZOOMIN)
  301.                               scale.i = SPDiv(SPFlt(max_x), 
  302.                                     SPFlt(ZoomBoxSizeX));
  303.                            else scale.i = SPDiv(SPFlt(10), SPFlt(1));
  304.                            ZoomAlongDarling(scale.i, SPFlt(1));
  305.                            if (ITEMNUM(code) == ZOOM_ZOOMIN)
  306.                               scale.i = SPDiv(SPFlt(max_y), 
  307.                                     SPFlt(ZoomBoxSizeY));
  308.                            else scale.i = SPDiv(SPFlt(10), SPFlt(1));
  309.                            ZoomAlongDarling(SPFlt(1), scale.i);
  310.  
  311.                            if (gen_mand()) return;
  312.                            break;
  313.                         case ZOOM_ZOOMOUT2:
  314.                            ZoomAlongDarling(SPFlt(2), SPFlt(2));
  315.                            if (gen_mand()) return;
  316.                            break;
  317.                         case ZOOM_ZOOMOUT10:
  318.                            ZoomAlongDarling(SPFlt(10), SPFlt(10));
  319.                            if (gen_mand()) return;
  320.                            break;
  321.                         }
  322.                      break; /* breaks MENU_ZOOM case statement */
  323.                   }
  324.                break; /* breaks MENUPICK switch statement */
  325.             case INTUITICKS:
  326.               code = NULL;
  327.             case MOUSEBUTTONS:
  328.               if (SettingCenter)
  329.                  {
  330.                  DrawZoomCenter();
  331.          if (code == SELECTDOWN) SettingCenter = FALSE;
  332.                  else
  333.                     {
  334.             ZoomCenterX = w->MouseX;
  335.             ZoomCenterY = w->MouseY;
  336.                     DrawZoomCenter();
  337.                     }
  338.                  }
  339.               else if (SettingBoxSize)
  340.                  {
  341.                  DrawZoomBox();
  342.          if (code == SELECTDOWN) SettingBoxSize = FALSE;
  343.                  else
  344.                     {
  345.                     RecalcZoomBox();
  346.                     DrawZoomBox();
  347.                     }
  348.                  }
  349.               break;
  350.             }
  351.          }
  352.       }
  353. }
  354.  
  355.  
  356. anal_mand()
  357. {
  358.    union kludge x_gap,y_gap,z_r,z_i,u_r,u_i,const0,const1,const2,const4;
  359.    union kludge const12,temp,temp2,temp3;
  360.    int count,x,y,width,height,last_x,last_y,select,lines;
  361.    ULONG class;
  362.    USHORT code;
  363.  
  364.    if (disp_mand())
  365.       return (1);
  366.  
  367.    x_gap.i = SPDiv(SPFlt(max_x),SPSub(start_r.i,end_r.i));
  368.    y_gap.i = SPDiv(SPFlt(max_y),SPSub(start_i.i,end_i.i));
  369.  
  370.    const0.i = SPFlt(0);
  371.    const1.i = SPFlt(1);
  372.    const2.i = SPFlt(2);
  373.    const4.i = SPFlt(4);
  374.    const12.i = SPDiv(SPFlt(2),SPFlt(1));
  375.  
  376.    last_x = -1;
  377.    last_y = -1;
  378.    select = 0;
  379.    lines = 0;
  380.  
  381.    aw.Screen = screen;
  382.    w2 = (struct Window *)OpenWindow(&aw);
  383.    if (w2 == NULL)
  384.    {
  385.       CloseDisplay();
  386.       fputs("Can't open analyzing window\n",console);
  387.       return (1);
  388.    }
  389.  
  390.    rp2 = w2->RPort;
  391.  
  392.    SetDrMd(rp2,JAM1);
  393.    SetBPen(rp2, 0);
  394.  
  395.    SetAPen(rp2, 1);
  396.    RectFill(rp2,LEFTW2+1,TOPW2+1,RIGHTW2-1,BOTTOMW2-1);
  397.  
  398.    for (EVER) {
  399.       if (message = (struct IntuiMessage *)GetMsg(w->UserPort)) {
  400.          class = message->Class;
  401.          code  = message->Code;
  402.          ReplyMsg(message);
  403.  
  404.          if (class == CLOSEWINDOW) {
  405.             CloseWindow(w2);
  406.             CloseDisplay();
  407.             return (0);
  408.          }
  409.          if (class == MOUSEBUTTONS)
  410.             if (code == SELECTDOWN) {
  411.                if (w->MouseY < STARTY)
  412.                   lines = !lines;
  413.                else
  414.                   select = TRUE;
  415.             }
  416.             else if (code == SELECTUP)
  417.                select = FALSE;
  418.       }
  419.       if ((last_x != w->MouseX || last_y != w->MouseY) && select &&
  420.           w->MouseX < max_x && w->MouseY >= STARTY && w->MouseY < max_y+STARTY) {
  421.          last_x = w-> MouseX;
  422.          last_y = w-> MouseY;
  423.          SetAPen(rp2,1);
  424.          RectFill(rp2,LEFTW2+1,TOPW2+1,RIGHTW2-1,BOTTOMW2-1);
  425.          width = RIGHTW2 - LEFTW2 - 6;
  426.          height = BOTTOMW2 - TOPW2 - 4;
  427.          SetAPen(rp2,3);
  428.          Move(rp2,LEFTW2+2,TOPW2+height/2+2);
  429.          Draw(rp2,RIGHTW2-2,TOPW2+height/2+2);
  430.          Move(rp2,LEFTW2+width/2+3,TOPW2+2);
  431.          Draw(rp2,LEFTW2+width/2+3,BOTTOMW2-2);
  432.          SetAPen(rp2,2);
  433.          if (func_num == 0)
  434.             z_r.i = const0.i;
  435.          else
  436.             z_r.i = const12.i;
  437.          z_i.i = const0.i;
  438.          u_r.i = SPAdd(start_r.i,SPMul(SPFlt(last_x),x_gap.i));
  439.          u_i.i = SPAdd(start_i.i,SPMul(SPFlt(max_y-(last_y-STARTY)-1),y_gap.i));
  440.          count = 0;
  441.          for (count=0;SPFix(SPAdd(SPMul(z_r.i,z_r.i),SPMul(z_i.i,z_i.i)))<4&&(count<max_count);count++) {
  442.  
  443.             temp.i = SPDiv(const4.i,SPMul(z_r.i,SPFlt(width)));
  444.             x = SPFix(temp.i);
  445.             temp.i = SPDiv(const4.i,SPMul(z_i.i,SPFlt(height)));
  446.             y = SPFix(temp.i);
  447.  
  448.             if (!lines)
  449.                if (x != 0 || y != 0)
  450.                   WritePixel(rp2,x+width/2+LEFTW2+3,height/2-y+TOPW2+2);
  451.                else ;
  452.             else
  453.                if (count == 0)
  454.                   Move(rp2,x+width/2+LEFTW2+3,height/2-y+TOPW2+2);
  455.                else
  456.                   Draw(rp2,x+width/2+LEFTW2+3,height/2-y+TOPW2+2);
  457.  
  458.             if (func_num == 0) {  /* z = z^2-u */
  459.                temp.i = SPSub(u_r.i,SPSub(SPMul(z_i.i,z_i.i),SPMul(z_r.i,z_r.i)));
  460.                z_i.i = SPSub(u_i.i,SPMul(SPMul(const2.i,z_r.i),z_i.i));
  461.                z_r = temp;
  462.             }
  463.             else if (func_num == 1) {  /* z = uz(1-z) */
  464.                temp2.i = SPSub(z_r.i,const1.i);
  465.                temp3.i = SPNeg(z_i.i);
  466.                temp.i = SPSub(SPMul(temp3.i,z_i.i),SPMul(temp2.i,z_r.i));
  467.                z_i.i = SPAdd(SPMul(temp2.i,z_i.i),SPMul(temp3.i,z_r.i));
  468.                z_r = temp;
  469.                temp.i = SPSub(SPMul(z_i.i,u_i.i),SPMul(z_r.i,u_r.i));
  470.                z_i.i = SPAdd(SPMul(z_r.i,u_i.i),SPMul(z_i.i,u_r.i));
  471.                z_r = temp;
  472.             }
  473.          }
  474.       }
  475.    }
  476. }
  477.  
  478. ZoomAlongDarling(rzoom, izoom)
  479. int rzoom, izoom;
  480. {
  481.    union kludge center,distance,scale;
  482.  
  483.       scale.i = rzoom;
  484.       distance.i = SPDiv(SPFlt(2),SPSub(start_r.i,end_r.i));
  485.       center.i = SPAdd(start_r.i,distance.i);
  486.       scale.i = SPMul(scale.i,distance.i);
  487.       start_r.i = SPSub(scale.i,center.i);
  488.       end_r.i = SPAdd(scale.i,center.i);
  489.  
  490.       scale.i = izoom;
  491.       distance.i = SPDiv(SPFlt(2),SPSub(start_i.i,end_i.i));
  492.       center.i = SPAdd(start_i.i,distance.i);
  493.       scale.i = SPMul(scale.i,distance.i);
  494.       start_i.i = SPSub(scale.i,center.i);
  495.       end_i.i = SPAdd(scale.i,center.i);
  496. }
  497.